﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.Runtime.CompilerServices;
using System.IO;
using System.Xml;
using HtmlAgilityPack;
using System.Text.RegularExpressions;

namespace Simple_search.Service
{
    public class EpubReader
    {
        public static string Read(string filePath)
        {
            StringBuilder mainStringBuilder = new();
            using (ZipArchive archive = ZipFile.OpenRead(filePath))
            {
                ZipArchiveEntry? opt = archive.GetEntry("OEBPS/content.opf");
                if (opt != null)
                {
                    using Stream optStream = opt.Open();
                    using XmlReader reader = XmlReader.Create(optStream);
                    Dictionary<string, string> contentMap = new();
                    List<string> spine = new();
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            switch (reader.Name)
                            {
                                case "item":
                                    string? id = reader["id"];
                                    string? href = reader["href"];
                                    if ((id != null) && (href != null))
                                    {
                                        href = "OEBPS/" + href;
                                        contentMap.Add(id, href);
                                    }
                                    break;
                                case "itemref":
                                    string? idref = reader["idref"];
                                    if (idref != null)
                                    {
                                        spine.Add(idref);
                                    }
                                    break;
                            }
                        }
                    }
                    foreach (string id in spine)
                    {
                        ZipArchiveEntry? entry = archive.GetEntry(contentMap[id]);
                        if (entry != null)
                        {
                            using Stream entryStream = entry.Open();
                            using StreamReader streamReader = new(entryStream, Encoding.UTF8);
                            HtmlDocument htmlDocument = new();
                            htmlDocument.Load(streamReader);
                            StringBuilder sb = new();
                            foreach (HtmlNode node in htmlDocument.DocumentNode.SelectNodes("//text()"))
                            {
                                sb.AppendLine(node.InnerText.Trim());
                            }
                            string contentText = sb.ToString();
                            mainStringBuilder.AppendLine(contentText);
                        }
                    }
                    Regex remove = new(@"[\u0002|\u0003|\u0000]");
                    return remove.Replace(mainStringBuilder.ToString(), string.Empty);
                } else
                {
                    throw new Exception("can't parse epub file");
                }
            }
        }

    }
}
